﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Compilation;
using System.ComponentModel;
using System.CodeDom;
using System.Web;

namespace LanguageConfigurationSolution
{
    [ExpressionPrefix("LanguageConfiguration")]
    public class LanguageExpressionBuilder : ExpressionBuilder
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entry"></param>
        /// <param name="parsedData"></param>
        /// <param name="context"></param>
        /// <returns>
        /// This method will return an CodeExpression which instructs to call the GetEvalData-method. 
        /// By doing this, the value gets refreshed on every page-request. 
        /// Otherwise the value would be fixed at page-compile-time (ie. first request).
        /// </returns>
        public override System.CodeDom.CodeExpression GetCodeExpression(System.Web.UI.BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
        {
            Type type = entry.DeclaringType;
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(type)[entry.PropertyInfo.Name];
            CodeExpression[] parameters = new CodeExpression[3];
            parameters[0] = new CodePrimitiveExpression(entry.Expression.Trim());
            parameters[1] = new CodeTypeOfExpression(type);
            parameters[2] = new CodePrimitiveExpression(entry.Name);

            return new CodeCastExpression(descriptor.PropertyType, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(GetType()), "GetEvalData", parameters));
        }

        public override bool SupportsEvaluate 
        { 
            get { return true; } 
        }

        public override object EvaluateExpression(object target, System.Web.UI.BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context)
        {
            return GetEvalData(entry.Expression.Trim(), entry.DeclaringType, entry.Name);
        }

        public static object GetEvalData(string expression, Type target, string entry)
        {
            if (HttpContext.Current == null || HttpContext.Current.Request == null)
            {
                return string.Empty;
            }

            string[] parts = expression.Split(new char[] { ',' });
            string Key ;
            switch (parts.Length)
            {
                case 1 :
                    Key = parts[1];
                    return ConfigurationReader.GetConfigurationValue(Key, string.Empty, "");
                case 2:
                    string listname = parts[0];
                    Key = parts[1];
                    return ConfigurationReader.GetConfigurationValue(Key, listname, "");
                default :
                    throw new ArgumentException("Expected parameter in the format '<ListName>,<Key>'");
            }            
        }
    }
}
